package com.nd.android.u.filestoragesystem.business.com;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;

import org.apache.http.HttpStatus;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ByteArrayBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;

import com.common.allCommon.ImageUploadUtils;
import com.common.android.utils.http.HttpException;
import com.common.android.utils.httpRequest.AutoLoginHttpRequest;
import com.common.android.utils.httpRequest.IHttpRequest;
import com.nd.android.u.filestoragesystem.business.FileSystemUtil;
import com.nd.android.u.filestoragesystem.business.bean.ParamKey;
import com.nd.android.u.filestoragesystem.business.bean.UploadImageParams;
import com.nd.android.u.filestoragesystem.externalInterface.FileConstant.FilePath;
import com.nd.android.u.filestoragesystem.externalInterface.FileUtilFactory;
import com.nd.android.u.filestoragesystem.externalInterface.IFile;
import com.nd.android.u.filestoragesystem.externalInterface.IFolder;
import com.nd.android.u.filestoragesystem.externalInterface.IInterActionAttr;
import com.product.android.business.config.Configuration;
import com.product.android.utils.HttpErrMsgUtils;
import com.common.allCommon.MD5Arithmetic;
/**
 * 文件系统请求
 * 
 * <br>Created 2014-6-16 下午3:32:14
 * @version  
 * @author   huangszh		
 *
 * @see
 */
public class NdFileStorageSdk {

    private Context mContext;
    
    /**
     * 默认获取数据大小为20
     */
    public final static int PAGE_SIZE = 20;
    
    /**
     * 
     * Creates a new instance of NdFileStorageSdk.
     * <br>Created 2014-6-16 下午3:31:49
     * @param context 上下文
     */
    public NdFileStorageSdk(Context context) {
        mContext = context;
    }
    
    
    /**
     * 上传url
     */
    public final static String UPLOAD_URL = FileUtilFactory.getInstance().getBaseUrl() + "files";
    
    /**
     * 获取列表
     */
    public final static String LIST_URL_FLOLDER = FileUtilFactory.getInstance().getBaseUrl() + "folders/list";
    
    /**
     * 获取文件列表
     */
    public final static String LIST_URL_FILE = FileUtilFactory.getInstance().getBaseUrl() + "files/list";
    
    /**
     * 上传文件（照片，团徽） ,只适用单线程上传；分块上传需要另外特殊处理
     * 
     * <br>Created 2014-6-12 上午9:57:13
     * @param params 请求参数
     * @return  long 文件id，成功才会返回
     * @throws JSONException   json异常
     * @throws HttpException 请求处理错误
     * @author        :  huangszh
     * @throws IOException 
     */
    public long upload(UploadImageParams params) 
            throws JSONException, HttpException, IOException {
        
        IHttpRequest request = getFileStorageRequest(mContext);
        MultipartEntity entity = new MultipartEntity(
                HttpMultipartMode.BROWSER_COMPATIBLE, null, Charset.forName("utf-8"));
        File file = new File(params.local_path);
        ByteArrayBody body = ImageUploadUtils.getImageByteArrayBody(mContext, file);
        if(body == null) {
        	return 0;
        }
        entity.addPart("file",body);
        entity.addPart(ParamKey.TYPE, new StringBody(String.valueOf(params.type)));
        entity.addPart(ParamKey.SID, new StringBody(params.sid));
        entity.addPart(ParamKey.ID,new StringBody(String.valueOf(params.id)));
        params.md5 = MD5Arithmetic.getFileMD5String(file);
        entity.addPart(ParamKey.MD5,new StringBody(params.md5));
        entity.addPart(ParamKey.PATH,new StringBody(params.path, Charset.forName("utf-8")));
        entity.addPart(ParamKey.NAME,new StringBody(file.getName(), Charset.forName("utf-8")));
        entity.addPart(ParamKey.SET_DEFAULT,new StringBody(String.valueOf(params.set_default)));
        if(params.info != null) {
            entity.addPart(ParamKey.INFO,new StringBody(params.info.toString(), Charset.forName("utf-8")));
        }
        if(params.local != null) {
            entity.addPart(ParamKey.LOCAL,new StringBody(params.local, Charset.forName("utf-8")));
        }
        entity.addPart(ParamKey.SIZE,new StringBody(String.valueOf(body.getContentLength())));
       
        StringBuilder receive = new StringBuilder();
        int iRet = request.doPost(UPLOAD_URL, entity, receive);
        JSONObject result = new JSONObject(receive.toString());
        if(iRet == HttpStatus.SC_OK) {
        	
        	/**业务错误，返回-1*/
        	if (result.has("code") && result.has("msg")){
        		return -1;
        	}
            return result.optLong(ParamKey.FID);
        } else {
            HttpErrMsgUtils.parseHttpErrMsg(iRet, result);
            return 0;
        }
        
    }
    
    /**
     * 批量删除图片
     * 
     * <br>Created 2014-6-12 上午10:09:45
     * @param type 类型：0=个人、1=组织、2=群、3=资源，必选
     * @param sid sessionid
     * @param uid 用户uid
     * @param fids 图片id
     * @return  boolean
     * @throws JSONException   json异常
     * @throws HttpException 请求处理错误
     * @author        :  huangszh
     * @throws UnsupportedEncodingException 
     */
    public boolean deletePhotos(int type,String sid,long uid,ArrayList<Long> fids) 
            throws JSONException, HttpException, UnsupportedEncodingException {
        
        IHttpRequest request = getFileStorageRequest(mContext);
        StringBuilder receive = new StringBuilder();
        JSONObject param = new JSONObject();
        param.put(ParamKey.TYPE, type);
        param.put(ParamKey.SID, sid);
        param.put(ParamKey.ID, uid);
        param.put(ParamKey.FIDS, FileSystemUtil.INSTANCE.convertToJSONArray(fids));
        StringEntity s = new StringEntity(param.toString(), HTTP.UTF_8);
        s.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,
                "application/json"));
        s.setContentEncoding(new BasicHeader(HTTP.CONTENT_ENCODING,
                HTTP.UTF_8));
        int iRet = request.doDeleteWithEntity(UPLOAD_URL,s,receive);
        if(iRet == HttpStatus.SC_OK) {
        	try {
        		JSONObject json = new JSONObject(receive.toString());
        		if (json.has("code") && json.has("msg")){
        			return false;
        		}
        	}catch(Exception e){
        		e.printStackTrace();
        	}
            return true;
        } else {
        	HttpErrMsgUtils.parseHttpErrMsg(iRet, receive);
            return false;
        }
    }
    
    /**
     * 获取音乐/图片专辑列表
     * 
     * <br>Created 2014-6-12 下午2:50:54
     * @param type  类型：0=个人、1=组织、2=群、3=资源，必选
     * @param sid   session,必选
     * @param id    资源分类id: 1=音乐专辑 2=图片专辑 3=电影
     * @param requestClass  必选，分类：0=文件列表 1=目录列表 2=目录+文件列表，默认：0
     * @param id_max    返回小于该id的记录。可选，取第一页传Long.MAX_VALUE
     * @param id_min    返回大于该id的记录
     * @param sort  排序字段@Sort，可选。传null默认是主键id，time=按时间倒序排列
     * @param page_size 每页记录数。可选，默认20
     * @return ArrayList<IFolder>
     * @throws JSONException    json解析异常
     * @throws HttpException   请求错误异常
     * @author        :  huangszh
     */
    public ArrayList<IFolder> getMxAlbums(int type,String sid,long id,int requestClass,
            long id_max,long id_min,String sort, int page_size) throws JSONException, HttpException {
        
        IHttpRequest request = getFileStorageRequest(mContext);
       
        JSONObject params = new JSONObject();
        params.put(ParamKey.TYPE, type);
        params.put(ParamKey.SID, sid);
        params.put(ParamKey.ID, id);
        params.put(ParamKey.CLASS, requestClass);
        params.put(ParamKey.PATH, FilePath.PHOTO);// 专辑传这个
        if(sort != null) {
            params.put(ParamKey.SORT, sort);
        }
        if(id_max != 0){
            params.put(ParamKey.ID_MAX, id_max);
        }
        if(id_min != 0){
            params.put(ParamKey.ID_MIN, id_min);
        }
        if(page_size != PAGE_SIZE){
            params.put(ParamKey.PAGE_SIZE, page_size);
        }
        
        StringBuilder receive = new StringBuilder();
        int iRet = request.doPost(LIST_URL_FLOLDER, params, receive);
        if(iRet == HttpStatus.SC_OK) {
            // 特殊处理文件系统返回null也是成功。。SB的设计
            if(receive.toString().equals("null")) {
                return new ArrayList<IFolder>();
            }
            return parseFolderInfoList(new JSONArray(receive.toString()));
        } else {
        	HttpErrMsgUtils.parseHttpErrMsg(iRet, receive);
            return null;
        }
    }
    
    /**
     * 获取专辑的歌曲列表/获取单曲列表/获取JAY相册图片列表/获取电影列表
     * 
     * <br>Created 2014-6-12 下午3:05:25
     * @param type  类型：0=个人、1=组织、2=群、3=资源，必选
     * @param sid   session,必选
     * @param id    资源分类id: 1=音乐专辑 2=图片专辑 3=电影
     * @param folderid  文件夹id
     * @param path  文件路径
     * @param id_max    返回小于该id的记录。可选，取第一页的传Long.MAX_VALUE
     * @param id_min    返回大于该id的记录
     * @param page_size 每页记录数。可选，默认20
     * @return  ArrayList<IFile>
     * @throws JSONException   json异常
     * @throws HttpException 请求处理错误
     * @author        :  huangszh
     */
    public ArrayList<IFile> getFileList(int type,String sid,long id,long folderid,String path,
            long id_max,long id_min, int page_size) throws JSONException, HttpException {
        
        JSONObject params = new JSONObject();
        params.put(ParamKey.TYPE, type);
        params.put(ParamKey.SID, sid);
        params.put(ParamKey.ID, id);
        // 文件夹id与path二选一
        if(path != null) {
            // 获取电影列表时专用
            params.put(ParamKey.PATH, path);
        } else {
            params.put(ParamKey.FOLDERID, folderid);
        }
        if(id_max != 0){
            params.put(ParamKey.ID_MAX, id_max);
        }
        if(id_min != 0){
            params.put(ParamKey.ID_MIN, id_min);
        }
        if(page_size != PAGE_SIZE){
            params.put(ParamKey.PAGE_SIZE, page_size);
        }
        
        return getFileList(params);
    }
    
    /**
     * 获取个人相册图片列表
     * 
     * <br>Created 2014-6-12 下午3:18:28
     * @param type  类型：0=个人、1=组织、2=群、3=资源，必选
     * @param sid   session,必选
     * @param id    资源分类id: 1=音乐专辑 2=图片专辑 3=电影
     * @param id_max    最小的记录id。可选，默认0
     * @param id_min    最大的记录id。可选，默认0
     * @param page_size 每页记录数。可选，默认20
     * @return ArrayList<IFile>
     * @throws JSONException   json异常
     * @throws HttpException 请求处理错误
     * @author        :  huangszh
     */
    public ArrayList<IFile> getPersonalPhotoList(int type,String sid,long id,
            long id_max,long id_min,int page_size) throws JSONException, HttpException {
        
        JSONObject params = new JSONObject();
        params.put(ParamKey.TYPE, type);
        params.put(ParamKey.SID, sid);
        params.put(ParamKey.ID, id);
        params.put(ParamKey.PATH, FilePath.PHOTO);
        if(id_max != 0){
            params.put(ParamKey.ID_MAX, id_max);
        }
        if(id_min != 0){
            params.put(ParamKey.ID_MIN, id_min);
        }
        if(page_size != PAGE_SIZE){
            params.put(ParamKey.PAGE_SIZE, page_size);
        }
        
        return getFileList(params);
    }
    
    /**
     * 获取文件列表处理
     * 
     * <br>Created 2014-6-12 下午3:20:32
     * @param params   请求参数
     * @return ArrayList<IFile>
     * @throws JSONException   json异常
     * @throws HttpException 请求处理错误
     * @author        :  huangszh
     */
    private ArrayList<IFile> getFileList(JSONObject params) throws JSONException, HttpException {
        
        IHttpRequest request = FileSystemUtil.INSTANCE.getMiddleRequest();
        StringBuilder receive = new StringBuilder();
        int iRet = request.doPost(FileSystemUtil.INSTANCE.getMiddleUrl(LIST_URL_FILE)
                , params, receive);
        if(iRet == HttpStatus.SC_OK) {
            // 特殊处理文件系统返回null
            JSONObject result = new JSONObject(receive.toString());
            
            // 如果是业务异常，则返回null
            if (result.has("code") && result.has("msg")){
            	return null;
            }
            if(result.optJSONArray("data") == null) {
                return new ArrayList<IFile>();
            }
            return parseFileInfoList(result);
        } else {
        	HttpErrMsgUtils.parseHttpErrMsg(iRet, receive.toString());
            return null;
        }
    }
    
    /**
     * 解析文件夹列表
     * 
     * <br>Created 2014-6-18 下午8:13:15
     * @param objectArr    返回内容
     * @return  ArrayList<IFolder>
     * @author        :  huangszh
     * @throws JSONException 
     */
    private ArrayList<IFolder> parseFolderInfoList(JSONArray objectArr) throws JSONException {
        ArrayList<IFolder> infos = new ArrayList<IFolder>();
        int length = objectArr.length();
        for(int i=0; i < length ;i++) {
            infos.add(FileSystemUtil.INSTANCE.
                    parseFolderInfo(objectArr.getJSONObject(i)));
        }
        return infos;
    }
    
    /**
     * 解析文件列表
     * 
     * <br>Created 2014-7-2 下午1:43:59
     * @param object  返回的内容
     * @return  ArrayList<IFile>
     * @throws JSONException
     * @author        :  huangszh
     */
    private ArrayList<IFile> parseFileInfoList(JSONObject object) throws JSONException {
        ArrayList<IFile> infos = new ArrayList<IFile>();
        // 获取原始接口返回的文件信息
        JSONArray origial = object.optJSONArray("data");
        if(origial == null) {
            return null;
        }
        // 获取对应的互动信息
        JSONObject extra = object.optJSONObject("resc").optJSONObject("oid");
        int length = origial.length();
        IFile file;
        for(int i=0; i < length ;i++) {
            // 解析基本文件信息
            file = FileSystemUtil.INSTANCE.parseFileInfo(origial.getJSONObject(i));
            if(extra != null) {
                // 解析文件对应的互动信息
                IInterActionAttr attr = FileSystemUtil.INSTANCE.parseInterActionAttr(file.getFid(), extra);
                file.setInterActionAttr(attr);
            }
            infos.add(file);
        }
        return infos;
    }

    /**
     * 获取文件存储系统的http请求
     * 
     * <br>Created 2014-6-12 上午9:57:41
     * @param ctx 上下文
     * @return IHttpRequest
     * @author        :  huangszh
     */
    private IHttpRequest getFileStorageRequest(Context ctx) {        
        IHttpRequest request = AutoLoginHttpRequest.getInstance(ctx,Configuration.OAP_APPID,1);
        request.setAgent(new FileStorageRequestHeader());
        return request;
    }
    

}
